home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / tip / out-ds.tip < prev    next >
Text File  |  1993-09-15  |  15KB  |  444 lines

  1. % This macro source file is from the four volume series
  2. % "TeX in Practice" by Stephan von Bechtolsheim, published
  3. % 1993 by Springer-Verlag, New York.
  4. % Copyright 1993 Stephan von Bechtolsheim.
  5. % No warranty or liability is assumed.
  6. % This macro may be copied freely if no fees other than
  7. % media cost or shipping charges are charged and as long
  8. % as this copyright and the following source code itself
  9. % is not changed. Please see the series for further information.
  10. %
  11. % Version: 1.0
  12. % Date: May 1, 1993
  13. %
  14. %
  15. % This source code is documented in 37.2.7.1, p. IV-170.
  16. % Original source in file "o4.TEX", starting line 461.
  17. \wlog{L: "out-ds.tip" ["o4.TEX," l. 461, p. IV-170]}%
  18. % This file DOES NOT belong to format "texip."
  19. \InputD{box-mac.tip}
  20. \InputD{rangetst.tip}
  21. \InputD{maxmindi.tip}
  22. \InputD{prot.tip}
  23. \InputD{vtbox.tip}
  24. \InputD{nathd.tip}
  25. \InputD{shiftudb.tip}
  26. \catcode`\@ = 11
  27. \newdimen\@PageWidth
  28. \newdimen\@ColWidth
  29. \newdimen\@ColIndent
  30. \newdimen\@PageHeight
  31. \newcount\@DSCCurNumberOfColumns
  32. \newcount\@PageLayoutCodeDSC
  33. \newcount\@DSCDebugging
  34. \def\SetUpDSC #1#2#3#4#5#6{%
  35.     \@DSCDebugging = #6
  36.     \CheckZeroOneRange{\@DSCDebugging}%
  37.         {\string\SetUpDSC: debugging code wrong}
  38.     \ifnum\@DSCDebugging = 0
  39.         \ProtWritefalse
  40.     \else
  41.         \ProtWritetrue
  42.     \fi
  43.     \InitProtWrite
  44.     \WriteProtocol{0}{\string\SetUpDSC: begin}%
  45.     \@PageWidth = #1%
  46.     \@ColWidth = #2%
  47.     \@ColIndent = #3%
  48.     \@PageHeight = #4%
  49.     \@PageLayoutCodeDSC = #5%
  50.     \CheckZeroOneRange{\@PageLayoutCodeDSC}%
  51.         {\string\SetUpDSC: page layout code wrong}%
  52.     \hsize = \@PageWidth
  53.     \dimen0 = 2\@ColIndent
  54.     \advance\dimen0 by 2\@ColWidth
  55.     \ifdim\dimen0 > \hsize
  56.         \errmessage{\string\SetUpDSC: Initial values of
  57.             \string\hsize, \noexpand\@ColWidth and
  58.             \noexpand\@ColIndent do not make sense.}%
  59.     \fi
  60.     \vsize = \@PageHeight
  61.     \@DSCCurNumberOfColumns = 1
  62.     \@SetSingleColumnOutput{As part of \string\SetUpDSC}% 
  63.     \ifcase \@PageLayoutCodeDSC
  64.         \topskip = 10pt             % Top / bottom flush
  65.     \or
  66.         \topskip = 10pt plus 50pt   % Ragged bottom
  67.     \else
  68.         \errmessage{\string\SetUpDSC: illegal
  69.             page layout parameter.}%
  70.     \fi
  71.     \WriteProtocol{0}{\string\SetUpDSC: end}%
  72. }
  73. \def\UnDoDSC{%
  74.     \global\output = {\plainoutput}%
  75. }
  76. \newbox\@BoxOfPageSoFar
  77. \newbox\@DSCLeftColumnBox
  78. \newdimen\@DSCLeftNaturalHeight
  79. \newbox\@DSCRightColumnBox
  80. \newdimen\@DSCRightNaturalHeight
  81. \newbox\@DSCTempBox
  82. \def\@EliminateRulesConditional{% 
  83.     \ifnum\@DSCDebugging = 0
  84.         \EliminateRuledBoxes
  85.     \fi
  86. }
  87. \newif\if@CaseCPageBreak
  88. \def\@EjectPenalty{-10000 }
  89. \def\eject{\penalty\@EjectPenalty}
  90. \def\@BalancePenalty{-10001 }
  91. \def\@PageLine{\hbox to \@PageWidth}
  92. \def\@PageLineR{\HboxR to \@PageWidth}
  93. \def\@ProtDSC #1{
  94.     \WriteProtocol{1}{\string\@ProtDSC: Begin (page \the\pageno)}
  95.     \WriteProtocol{2}{"#1",
  96.         number of cols: \the\@DSCCurNumberOfColumns}
  97.     \WriteProtocol{2}{\string\vsize: \the\vsize,
  98.         \string\pagetotal: \the\pagetotal,
  99.         \string\pagegoal: \the\pagegoal}
  100.     \BoxToProtocol{2}{\@BoxOfPageSoFar}{}
  101.     \WriteProtocol{2}{\string\dimen0: \the\dimen0,
  102.         \string\outputpenalty: \the\outputpenalty}
  103.     \WriteProtocol{1}{\string\@ProtDSC: End}
  104. }
  105. \def\@CaseReport #1{%
  106.     \WriteProtocol{0}{CASE #1}%
  107.     \message{CASE #1.}%
  108. }
  109. \def\@SetOutputRoutine #1#2#3{%
  110.     #1\output = {#2}% 
  111.     \WriteProtocol{0}{\string\@SetOutputRoutine:}%
  112.     \WriteProtocol{1}{#3}%
  113. }
  114. \def\@SingleColumnOutputRoutine{% 
  115.     \@EliminateRulesConditional
  116.     \WriteProtocol{0}{\noexpand\@SingleColumnOutputRoutine called,
  117.         \noexpand\outputpenalty is \the\outputpenalty}
  118.     \WriteProtocol{1}{Page number is \the\pageno}
  119.     \showboxdepth   = 2
  120.     \showboxbreadth = 1000
  121.     \@ProtDSC{\string\@SingleColumnOutputRoutine: begin}%
  122.     \BoxToProtocol{1}{255}{}%
  123.     \@CheckNumberOfColumns{1}{\@SingleColumnOutputRoutine}%
  124.     \@ShipAPageBox{%
  125.         \ifnum\@PageLayoutCodeDSC = 0
  126.             \vbox to \@PageHeight{\unvbox 255}%
  127.         \else
  128.             \vbox to \@PageHeight{\unvbox 255 \vfill}%
  129.         \fi
  130.     }%
  131. }
  132. \def\@SetSingleColumnOutput #1{%
  133.     \WriteProtocol{0}{\string\@SetSingleColumnOutput: set to single
  134.                 column output!}%
  135.     \global\@DSCCurNumberOfColumns = 1
  136.     \@SetOutputRoutine{\global}{\@SingleColumnOutputRoutine}{#1}%
  137.     \global\vsize    = \@PageHeight
  138.     \global\pagegoal = \@PageHeight
  139. }
  140. \def\@SaveCurrentPageOutputRoutine{% 
  141.     \global\setbox\@BoxOfPageSoFar = \vbox{\unvbox 255}%
  142.     \BoxToProtocol{0}{\@BoxOfPageSoFar}% 
  143.         {\string\@SaveCurrentPageOutputRoutine}
  144. }
  145. \newcount\@VsizeFactor
  146. \def\@ComputeVsizeForDoubleColumns{% 
  147.     \vsize = \@PageHeight
  148.     \advance\vsize by -\ht\@BoxOfPageSoFar
  149.     \advance\vsize by -\dp\@BoxOfPageSoFar
  150.     \multiply\vsize by 2
  151.     \@VsizeFactor = \vsize
  152.     \divide\@VsizeFactor by \baselineskip
  153.     \ifodd\@VsizeFactor
  154.         \advance\@VsizeFactor by -1
  155.     \fi
  156.     \global\vsize = \@VsizeFactor \baselineskip
  157.     \@ProtDSC{\string\@ComputeVsizeForDoubleColumns}% 
  158. }
  159. \newdimen\@HalfVsize
  160. \def\@ComputeHalfVsize{% 
  161.     \@HalfVsize = \vsize
  162.     \divide\@HalfVsize by 2
  163. }
  164. \def\BeginDoubleColumns{%
  165.     \par
  166.     \WriteProtocol{0}{\string\BeginDoubleColumns: begin}
  167.     \@CheckNumberOfColumns{1}{\BeginDoubleOfColumns}% 
  168.     \global\@DSCCurNumberOfColumns = 2
  169.     \begingroup
  170.     \@CaseCPageBreakfalse
  171.     \@EliminateRulesConditional
  172.     \WriteProtocol{1}{\string\BeginDoubleColumns: put rest of page
  173.                             into \string\@BoxOfPageSoFar}%
  174.     \@SetOutputRoutine{}{\@SaveCurrentPageOutputRoutine}%
  175.         {\string\BeginDoubleColumns: save page built up to now.}%
  176.     \eject
  177.     \@ProtDSC{\string\BeginDoubleColumns: 2}%
  178.     \@SetOutputRoutine{}{\@DoubleColumnOutputRoutine}% 
  179.         {Double column output set up by \string\BeginDoubleColumns}%
  180.     \hsize = \@ColWidth
  181.     \@ComputeVsizeForDoubleColumns
  182.     \@ProtDSC{\string\BeginDoubleColumns: 3}%
  183. }
  184. \def\EndDoubleColumns{%
  185.     \par
  186.     \WriteProtocol{0}{\string\EndDoubleColumns: begin}
  187.     \@CheckNumberOfColumns{2}{\EndDoubleOfColumns}
  188.     \@ProtDSC{In \string\EndDoubleColumns}
  189.     \@CaseReport{A}
  190.     \penalty\@BalancePenalty
  191.     \@BuildPageSoFar
  192.     \@SetSingleColumnOutput{\string\EndDoubleColumns}
  193.     \endgroup
  194. }
  195. \def\@DoubleColumnOutputRoutine{%
  196.     \@EliminateRulesConditional
  197.     \WriteProtocol{0}{\string\@DoubleColumnOutputRoutineput:
  198.                     begin (penalty: \the\outputpenalty)}
  199.     \if@CaseCPageBreak
  200.         \@CaseReport{D/E}%
  201.         \ifvoid\@DSCLeftColumnBox
  202.             \errmessage{\string\@DoubleColumnOutputRoutine:
  203.                 missing left column!}%
  204.         \else
  205.             \ifvoid\@DSCRightColumnBox
  206.                 \global\setbox\@DSCRightColumnBox =
  207.                     \vbox{\unvbox 255}%
  208.                 \global\@DSCRightNaturalHeight =
  209.                     \ht\@DSCRightColumnBox
  210.                 \ifnum\outputpenalty = \@EjectPenalty
  211.                     \errmessage{\string\@DoubleColumnOutput:
  212.                         \noexpand\eject in right column illegal.}%
  213.                     \@CaseReport{D}
  214.                     \MaxDimen{\dimen0}{\@DSCRightNaturalHeight}% 
  215.                                       {\@DSCLeftNaturalHeight}{}%
  216.                 \else
  217.                     \ifnum\outputpenalty = \@BalancePenalty
  218.                         \@CaseReport{E}
  219.                         \MaxDimen{\dimen0}{\@DSCRightNaturalHeight}
  220.                                           {\@DSCLeftNaturalHeight}{}%
  221.                     \else
  222.                         \@CaseReport{D}%
  223.                         \dimen0 = \vsize
  224.                     \fi
  225.                 \fi
  226.                 \@SetColumnBox{\@DSCLeftColumnBox}{}% 
  227.                 \@SetColumnBox{\@DSCRightColumnBox}{}%
  228.                 \Vtbox{\@DSCRightColumnBox}{\global}%
  229.                 \ShiftRefPointUpOrDown{\@DSCRightColumnBox}{12pt}%
  230.                 \Vtbox{\@DSCLeftColumnBox}{\global}%
  231.                 \ShiftRefPointUpOrDown{\@DSCLeftColumnBox}{12pt}%
  232.                 \ifnum\outputpenalty > -10000
  233.                     \@ShipAPageBox{%
  234.                         \ifnum\@PageLayoutCodeDSC = 0
  235.                             \vbox to \@PageHeight{\@BuildPageSoFar}%
  236.                         \else
  237.                             \vbox to \@PageHeight{\@BuildPageSoFar
  238.                                                         \vfill}%
  239.                         \fi
  240.                     }%
  241.                 \else
  242.                     % It's \EndDoubleColumns!
  243.                 \fi
  244.                 \global\@CaseCPageBreakfalse
  245.                 \@ComputeVsizeForDoubleColumns
  246.                 \global\pagegoal = \vsize
  247.             \else
  248.                 \errmessage{\string\@DoubleColumnOutputRoutine:
  249.                         left / right columns messed up.}
  250.             \fi
  251.         \fi     
  252.     \else
  253.         \ifnum\outputpenalty = \@EjectPenalty
  254.             \@CaseReport{C}
  255.             \WriteProtocol{1}{\string\@DoubleColumnOutputRoutineput:
  256.                         penalty \@EjectPenalty call.}
  257.             \global\@CaseCPageBreaktrue
  258.             \ifvoid\@DSCLeftColumnBox
  259.                 \global\setbox\@DSCLeftColumnBox =
  260.                     \vbox{\unvbox 255}
  261.                 \global\@DSCLeftNaturalHeight = \ht\@DSCLeftColumnBox
  262.                 \@ComputeHalfVsize
  263.                 \WriteProtocol{2}{*\string\vsize/2 is
  264.                                         \the\@HalfVsize}%
  265.                 \dimen1 = \ht\@DSCLeftColumnBox
  266.                 \advance\dimen1 by \dp\@DSCLeftColumnBox
  267.                 \ifdim\dimen1 > \@HalfVsize
  268.                     \message{WARNING: column is to long!}%
  269.                 \fi
  270.                 \global\pagegoal = \@HalfVsize
  271.                 \global\vsize    = \@HalfVsize
  272.             \else
  273.                 \errmessage{\string\@DoubleColumnOutputRoutine:
  274.                     left column box already loaded!}%
  275.             \fi
  276.         \else
  277.             \@StandardBalanceColumns
  278.             \ifnum\outputpenalty = \@BalancePenalty
  279.                 \@CaseReport{A}% 
  280.             \else
  281.                 \@CaseReport{B}% 
  282.                 \@ShipAPageBox{%
  283.                     \ifnum\@PageLayoutCodeDSC = 0
  284.                         \vbox to \@PageHeight{\@BuildPageSoFar}%
  285.                     \else
  286.                         \vbox to \@PageHeight{\@BuildPageSoFar
  287.                                                         \vfill}%
  288.                     \fi
  289.                 }%
  290.                 \@ComputeVsizeForDoubleColumns
  291.                 \global\pagegoal = \vsize
  292.             \fi
  293.         \fi
  294.     \fi
  295. }
  296. \newcount\@EmptyBoxesBuildPageCount
  297. \def\@BuildPageSoFar{%
  298.     \@EmptyBoxesBuildPageCount = 0
  299.     \ifvoid\@BoxOfPageSoFar
  300.         \advance\@EmptyBoxesBuildPageCount by 1
  301.     \fi
  302.     \ifvoid\@DSCLeftColumnBox
  303.         \advance\@EmptyBoxesBuildPageCount by 1
  304.     \fi
  305.     \ifvoid\@DSCRightColumnBox
  306.         \advance\@EmptyBoxesBuildPageCount by 1
  307.     \fi
  308.     \WriteProtocol{1}{\string\@BuildPageSoFar: begin
  309.             (\noexpand\@EmptyBoxesBuildPageCount is
  310.             \the\@EmptyBoxesBuildPageCount)}
  311.     \ifnum\@EmptyBoxesBuildPageCount < 3
  312.         \BoxToProtocol{2}{\@BoxOfPageSoFar}{}
  313.         \BoxToProtocol{2}{\@DSCLeftColumnBox}{}
  314.         \BoxToProtocol{2}{\@DSCRightColumnBox}{}
  315.         \unvbox\@BoxOfPageSoFar         % May be empty.
  316.         \wd\@DSCLeftColumnBox = \@ColWidth      % Left column.
  317.         \wd\@DSCRightColumnBox = \@ColWidth     % Right column.
  318.         \@PageLine{%
  319.             \hskip\@ColIndent
  320.             \BoxR\@DSCLeftColumnBox
  321.             \hfil
  322.             \BoxR\@DSCRightColumnBox
  323.             \hskip\@ColIndent
  324.         }
  325.         \smallskip
  326.     \fi
  327.     \WriteProtocol{1}{\string\@BuildPageSoFar: end}
  328. }
  329. \def\@SetColumnBox #1#2{% 
  330.     \global\setbox#1 = \vbox to \dimen0{\unvbox#1 #2}%
  331.     \Vtbox{#1}{\global}%
  332.     \ShiftRefPointUpOrDown{#1}{12pt}%
  333. }
  334. \def\@StandardBalanceColumns{% 
  335.     \setbox\@DSCTempBox = \vbox{\unvcopy 255}
  336.     \dimen0 = \ht\@DSCTempBox
  337.     \advance\dimen0 by \dp\@DSCTempBox
  338.     \advance\dimen0 by \topskip
  339.     \divide\dimen0 by 2
  340.     \WriteProtocol{1}{\string\@StandardBalanceColumns:
  341.         \noexpand\dimen0 is \the\dimen0, page \the\pageno.}
  342.     \@BalanceColumns{\dimen0}%
  343. }
  344. \def\@BalanceColumns #1{%
  345.     \@ProtDSC{\string\@BalanceColumns: Start}%
  346.     \@EliminateRulesConditional
  347.     \ifvoid\@DSCLeftColumnBox\else
  348.         \errmessage{\string\@BalanceColumns: left column box
  349.             not empty.}%
  350.     \fi
  351.     \ifvoid\@DSCRightColumnBox\else
  352.         \errmessage{\string\@BalanceColumns: right column box
  353.             not empty.}%
  354.     \fi
  355.     \ifvoid 255
  356.         \errmessage{\string\@BalanceColumns: box 255 is void.}%
  357.     \fi
  358.     \setbox\@DSCTempBox = \vbox{\unvbox 255}
  359.     \dimen0 = #1
  360.     \splittopskip = \topskip
  361.     \BoxToProtocol{0}{\@DSCTempBox}{Before \noexpand\vsplit loop}%
  362.     {%
  363.         \vbadness = 10000   % Don't report underfull boxes.
  364.         \loop
  365.             \global\setbox\@DSCRightColumnBox = \copy\@DSCTempBox
  366.             \global\setbox\@DSCLeftColumnBox =
  367.                     \vsplit\@DSCRightColumnBox to \dimen0
  368.             \WriteProtocol{1}{\string\dimen0: \the\dimen0}%
  369.             \BoxToProtocol{1}{\@DSCLeftColumnBox}% 
  370.                 {[1] (left column) in \noexpand\vsplit loop}%
  371.             \BoxToProtocol{1}{\@DSCRightColumnBox}%
  372.                 {[2] (right column) in \noexpand\vsplit loop}%
  373.             \NaturalHeight{\dimen3}{\@DSCLeftColumnBox}%
  374.             \NaturalHeight{\dimen4}{\@DSCRightColumnBox}%
  375.             \WriteProtocol{3}{\string\dimen3: \the\dimen3}%
  376.             \WriteProtocol{3}{\string\dimen4: \the\dimen4}%
  377.             \advance\dimen3 by 1sp
  378.             \ifdim\dimen4 > \dimen3
  379.                 \global\advance\dimen0 by 1pt
  380.         \repeat
  381.     }
  382.     \setbox\@DSCLeftColumnBox  = \vbox{\unvbox\@DSCLeftColumnBox}%
  383.     \setbox\@DSCRightColumnBox  = \vbox{\unvbox\@DSCRightColumnBox}%
  384.     \MaxDimen{\dimen0}{\ht\@DSCLeftColumnBox}% 
  385.                     {\ht\@DSCRightColumnBox}{}%
  386.     \ifcase\@PageLayoutCodeDSC
  387.         \@SetColumnBox{\@DSCLeftColumnBox}{}%
  388.         \@SetColumnBox{\@DSCRightColumnBox}{}%
  389.     \or
  390.         \@SetColumnBox{\@DSCLeftColumnBox}{\vfill}%
  391.         \@SetColumnBox{\@DSCRightColumnBox}{\vfill}%
  392.     \fi
  393.     \WriteProtocol{1}{\string\@BalanceColumns:
  394.         balancing done.}%
  395. }
  396. \def\DSCHeader{% 
  397.     \@PageLineR{% 
  398.         \bf Header
  399.         \hfil
  400.         \tt \the\pageno
  401.     }%
  402. }
  403. \def\DSCFooter{%
  404. %   \@PageLineR{% 
  405. %       \vrule width \@PageWidth height 1pt depth 2pt
  406. %   }% 
  407.     \@PageLineR{% 
  408.         \bf FOOTER
  409.         \hfil
  410.         \tt \the\pageno
  411.     }%
  412. }
  413. \def\@ShipAPageBox #1{%
  414.     \WriteProtocol{0}{\string\@ShipAPageBox:
  415.         called (page \the\pageno)}%
  416.     \shipout\vbox{%
  417.         \@EliminateRulesConditional
  418.         \DSCHeader
  419.         \vskip 12pt
  420.         #1
  421.         \vskip 12pt
  422.         \DSCFooter
  423.     }
  424.     \WriteProtocol{0}%
  425.         {\string\@ShipAPageBox: done (page \the\pageno)}%
  426.     \advancepageno
  427. }
  428. \def\@CheckNumberOfColumns #1#2{%
  429.     \ifnum \@DSCCurNumberOfColumns = #1\relax
  430.     \else
  431.         \errmessage{\string\@CheckNumberOfColumns: [\string#2]:
  432.             currently \the\@DSCCurNumberOfColumns\space columns,
  433.             should be #1.}
  434.     \fi
  435. }
  436. \def\bye{}
  437. \def\bye{% 
  438.     \@CheckNumberOfColumns{1}{\string\bye: Still in double
  439.         column mode, forgotten a \string\EndDoubleColumns?}%
  440.     \vfill\supereject
  441.     \end
  442. }
  443. \catcode`\@ = 12
  444.